#pragma once

#include "D3DDeviceProxy.h"

namespace Vortex { namespace Wrapper { namespace Direct3D {

	public delegate void UpdateFloatConstantHandler(unsigned int registerIndex, const float* pData, unsigned int vector4fCount);
	public delegate void UpdateIntConstantHandler(unsigned int registerIndex, const int* pData, unsigned int vector4iCount);
	public delegate void UpdateBoolConstantHandler(unsigned int registerIndex, const BOOL* pData, unsigned int boolCount);

	class D3DDeviceProxy;
	ref class Direct3DDevice9;

	///<summary>Wrapper of IDirect3DVertexConstantTable9 interface</summary>
	public ref class D3DXConstantTable : public ShaderConstantCallback {
		ID3DXConstantTable* _handle;
		D3DDeviceProxy* _proxy;

	public:

		///<summary>Direct3DDevice handle</summary>
		property IntPtr Handle { IntPtr get() { return IntPtr(_handle); } }

		property ID3DXConstantTable* NativeHandle { ID3DXConstantTable* get() { return _handle; } }

		D3DXConstantTable(ID3DXConstantTable* handle);

		~D3DXConstantTable();

		LPVOID GetBufferPointer();

		DWORD GetBufferSize();

		void SetDefaults();

		void SetDefaults(Direct3DDevice9^ device);

		IntPtr FindConstantHandleByName(String^ constName);

		HResult SetConstantData(IntPtr constantHandle, void* pData, UINT bytesCount); 

		HResult SetConstantData(Direct3DDevice9^ device, IntPtr constantHandle, void* pData, UINT bytesCount); 

		#pragma region ShaderConstantCallback members

		virtual void SetVertexShaderConstantF(UINT startRegister, const float* pData, UINT vector4fCount);
		virtual void SetVertexShaderConstantI(UINT startRegister, const int* pData, UINT vector4iCount);
		virtual void SetVertexShaderConstantB(UINT startRegister, const BOOL* pData, UINT boolCount);

		virtual void SetPixelShaderConstantF(UINT startRegister, const float* pData, UINT vector4fCount);
		virtual void SetPixelShaderConstantI(UINT startRegister, const int* pData, UINT vector4iCount);
		virtual void SetPixelShaderConstantB(UINT startRegister, const BOOL* pData, UINT boolCount);

		#pragma endregion

		///<summary>Invoked when float constants are changed</summary>
		UpdateFloatConstantHandler^ OnFloatConstantChange;
		///<summary>Invoked when int constants are changed</summary>
		UpdateIntConstantHandler^ OnIntConstantChange;
		///<summary>Invoked when boolean constants are changed</summary>
		UpdateBoolConstantHandler^ OnBoolConstantChange;
	
	};
}}}